package com.luiz.aero.android.connection;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

import com.luiz.aero.android.data.StaticPositionData;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import android.widget.Toast;

public class BluetoothConnection extends Thread {
	
	private final BluetoothSocket mmSocket;
	private final InputStream mmInStream;
	private final OutputStream mmOutStream;
	public byte[] buffer;
	public byte[] previousBuffer;
	private Properties properties = new Properties();
	private BluetoothAdapter btAdapter;
	private BluetoothDevice arduinoDevice = null;

	// Unique UUID for this application, you may use different
	private static final UUID MY_UUID = UUID
			.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

	public BluetoothConnection(String deviceName) throws Exception {
		//properties.load(new FileInputStream(new File(propFilePath)));

		btAdapter = BluetoothAdapter.getDefaultAdapter();

		if(!btAdapter.isEnabled()){
			btAdapter.enable();
		}

		Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
		// If there are paired devices
		if (pairedDevices.size() > 0) {
			// Loop through paired devices
			for (BluetoothDevice device : pairedDevices) {
				// Add the name and address to an array adapter to show in a ListView
				if(device.getName().equals(deviceName)){
					arduinoDevice = device;
				}
			}
			if(arduinoDevice == null){
				throw new Exception("Device not found");
			}
			
		}

		BluetoothSocket tmp = null;

		// Get a BluetoothSocket for a connection with the given BluetoothDevice
		try {
			tmp = arduinoDevice.createRfcommSocketToServiceRecord(MY_UUID);
		} catch (IOException e) {
			e.printStackTrace();
		}
		mmSocket = tmp;

		//now make the socket connection in separate thread to avoid FC
		Thread connectionThread  = new Thread(new Runnable() {

			@Override
			public void run() {
				// Always cancel discovery because it will slow down a connection
				btAdapter.cancelDiscovery();

				// Make a connection to the BluetoothSocket
				try {
					// This is a blocking call and will only return on a
					// successful connection or an exception
					mmSocket.connect();
				} catch (IOException e) {
					//connection to device failed so close the socket
					try {
						mmSocket.close();
					} catch (IOException e2) {
						e2.printStackTrace();
					}
				}
			}
		});

		connectionThread.start();

		InputStream tmpIn = null;
		OutputStream tmpOut = null;

		// Get the BluetoothSocket input and output streams
		try {
			tmpIn = mmSocket.getInputStream();
			tmpOut = mmSocket.getOutputStream();
			buffer = new byte[1024];
			previousBuffer = new byte[1024];
		} catch (IOException e) {
			e.printStackTrace();
		}

		mmInStream = tmpIn;
		mmOutStream = tmpOut;
	}

	public void run() {

		// Keep listening to the InputStream while connected
		while (true) {
			try {
				//read the data from socket stream
				mmInStream.read(buffer);
				
				if(!buffer.toString().equals(previousBuffer.toString())){
					StaticPositionData.servosPosition = parseBuffer();
					previousBuffer = buffer;
				}
				
				Thread.sleep(1000);
				// Send the obtained bytes to the UI Activity
			} catch (IOException e) {
				//an exception here marks connection loss
				cancel();
				//send message to UI Activity
				break;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	private int[] parseBuffer() {
		String bufferString = buffer.toString();
		String[] valuesString = bufferString.split(";");
		int[] valuesInt = new int[valuesString.length];
		int aux = 0;
		for(String value: valuesString){
			int valueInt = Integer.parseInt(value);
			valuesInt[aux] = valueInt;
			aux++;
		}
		return valuesInt;
	}

	public void write(byte[] buffer) {
		try {
			//write the data to socket stream
			mmOutStream.write(buffer);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void cancel() {
		try {
			mmSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean getStatus(){
		if(mmSocket!=null)return true;
		else return false;

	}
}